<!--
 * @Description: 
 * @Version: 2.0
 * @Autor: wiz
 * @Date: 2023-09-13 17:20:15
 * @LastEditors: swc
 * @LastEditTime: 2024-12-04 14:59:52
-->

<template>
  <div class="init-container">
    <div class="mask-container" v-if="isMask"></div>
    <div class="left-card-box">
      <o-card-box position="left" :width="150" :height="300">
        <div class="left-card-box-select">
          <RadioGroup v-model="selVal" vertical @on-change="selValOnChange">
            <Radio
              border
              v-for="(itm, index) of refComps"
              :key="index"
              :label="$srv.getI18nBySrv(itm.conf.name)"
            >
            </Radio>
          </RadioGroup>
        </div>
      </o-card-box>
    </div>
    <div class="init-container">
      <div
        class="init-container"
        v-show="item.show"
        v-for="(item, idx) of refComps"
        :key="idx"
      >
        <!-- loadDataInfo 当加载有数据时触发 -->
        <component
          :is="item.openCompName"
          v-bind="{
            config: item.conf,
            compBoxInfo: GT_compBoxInfo
          }"
          @load-data-info="loadDataInfo($event, idx)"
        ></component>
      </div>
    </div>
    <!-- <Carousel
      class="init-container"
      v-model="carouselIdx"
      dots="none"
      arrow="none"
    >
      <CarouselItem v-for="(item, idx) of refComps" :key="idx">
        <div class="init-container">
          <component
            :is="item.openCompName"
            v-bind="{
              config: item.conf,
              compBoxInfo: GT_compBoxInfo
            }"
            @load-data-info="loadDataInfo($event, idx)"
          ></component>
        </div>
      </CarouselItem>
    </Carousel> -->
  </div>
</template>

<script lang="ts">
import {
  I_cmd,
  N_oBaseGrid,
  N_oRefComp,
  N_oSetupPanel,
  T_cmd,
  T_srv,
  Tsrv,
  ifs,
  vue
} from './config';

@T_srv.comp
export default class oRefComp extends vue {
  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  config: N_oRefComp.I_conf;

  // _config副本 这样不会改到store里的数据
  private _config: any = null;

  /* 组件名 */
  private name: string = 'oRefComp';

  private G_compName: string = this.name;

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  /* 指挥部 */
  private GT_command: I_cmd = new T_cmd();

  private carouselIdx: number = 0;

  public isMask: boolean = false;

  // 组件配置
  private conf: any = null;

  private refComps: Array<N_oRefComp.I_openFunParams> = [];

  private custEventID: string = Tsrv.utils.custUUID(10, 16);

  private forwardCoordinations: Array<string> = [];

  private funName: string = '';

  public selVal: string = '';

  private totalReturnTable: Set<string> = new Set();

  // 监听类型
  private listenType: 'default' | 'magicbox' = 'default';

  // map <监听事件，源事件>
  private forward: Map<string, string> = new Map();

  created() {
    // 如果父组件没有传参，那就产生一个
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.GT_command.init(this, this.GT_compBoxInfo);
    this.init();
  }

  mounted() {
    /* 向父组件发送实例 */
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    /* 最终应用组件向外抛出引用实例,以供应用间调用 */
    Tsrv.compBox.addCompMergeName(
      Tsrv.compBox.getDefGUID(), // 全局compBox
      this.funName,
      this
    );
    this.listenEvent();
  }

  init() {
    this._config = Tsrv.utils.clone(this.config, true);
    if (this._config) {
      if (Tsrv.utils.noValue(this._config.refComps)) {
        return;
      }
      this.funName = this._config?.name || '';
      this.listenType = this._config['listenType'] || 'default';
      Promise.all(
        this._config.refComps.map(e => {
          return this.$store.dispatch('getLayoutConfigAsync', {
            funid: null,
            field: e.value.toTable,
            type: 'component'
          });
        })
      )
        .then(res => {
          res.forEach(e => {
            this.refComps.push({
              // show: this.refComps.length === 0,
              show: false,
              conf: this.getCompConfig(e.current.config),
              openCompName:
                e.current.name === 'BaseGrid'
                  ? Tsrv.utils.findComponent(e.current.name)
                  : ''
            });
          });
          // 默认显示第一个
          this.selValOnChange(Tsrv.getI18nBySrv(this.refComps[0].conf.name));
        })
        .catch(e => {
          console.error('请求数据出错', e);
          this.$msg(Tsrv.getI18nByValue('请求数据出错'));
        });
    }
  }

  getCompConfig(cf: any): any {
    if (Tsrv.utils.noValue(cf)) {
      return null;
    }
    const _cf = Tsrv.utils.clone(cf, true);
    _cf['mainFun'] = this._config.mainFun;
    _cf['listenType'] = this.listenType;
    _cf.messageConfig.custDefListener['search'] = [this.custEventID];
    if (_cf.messageConfig.custDefListener?.coordination) {
      this.forwardCoordinations.push(
        _cf.messageConfig.custDefListener.coordination
      );
    }
    // 改变组件的协调事件组
    _cf.messageConfig['eventGroup'] = this._config.messageConfig.eventGroup;

    _cf.tableDataSetting.autoload = false;
    return _cf;
  }

  // 谁加载谁显示
  loadDataInfo(p: N_oBaseGrid.I_loadDataInfo, idx: number) {
    if (p.total > 0) {
      this.totalReturnTable.add(p.funName);
      if (this.totalReturnTable.size > 1) {
        Tsrv.dialog.alert(
          Tsrv.getI18nByValue('引用组件有多个功能存在对应数据'),
          Tsrv.getI18nByValue('警告')
        );
      }
      this.refComps.forEach((el, index) => {
        if (index === idx) {
          this.selValOnChange(Tsrv.getI18nBySrv(el.conf.name));
        }
      });
    }
  }

  listenEvent() {
    let bus = this.$bus;
    if (this.listenType === 'magicbox') {
      bus = this.$mbus;
    }
    this._config.messageConfig.custDefListener.search.forEach(e => {
      bus.$on(e, p => {
        this.selValOnChange('');
        this.totalReturnTable.clear();
        // 转发事件
        Tsrv.reliablySendingBusEvent(this.custEventID, bus, 10, 100, p);
      });
    });
    if (this._config.messageConfig.custDefListener?.coordination) {
      bus.$on(this._config.messageConfig.custDefListener.coordination, p => {
        // 转发协作事件事件
        // this.GT_command.receEventCoordination(p);
        this.forwardCoordinations.forEach(e => {
          if (p?.fromComp?.fromEvenID !== e) {
            Tsrv.reliablySendingBusEvent(e, bus, 10, 100, p);
          }
        });
      });
    }
  }

  cleanSubCompData(p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar) {}

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
    /* 最终应用组件销毁 */
    Tsrv.compBox.removeCompMergeName(Tsrv.compBox.getDefGUID(), this.funName);
    this._config.messageConfig.custDefListener.search.forEach(e => {
      this.$bus.$off(e);
    });
    if (this._config.messageConfig.custDefListener?.coordination) {
      this.$bus.$off(this._config.messageConfig.custDefListener.coordination);
    }
  }

  private setAllHide() {
    this.refComps.forEach(el => {
      el.show = false;
    });
  }

  selValOnChange(e) {
    this.setAllHide();
    this.selVal = e;

    setTimeout(() => {
      this.refComps.forEach(el => {
        if (Tsrv.getI18nBySrv(el.conf.name) === e) {
          el.show = true;
        }
      });
    }, 0);
  }
}
</script>
<style lang="scss" scoped>
.init-container {
  ::v-deep .ivu-carousel-list,
  ::v-deep .ivu-carousel-item,
  ::v-deep .ivu-carousel-track {
    height: 100% !important;
  }
}
.left-card-box {
  position: relative;
  top: calc(50% - 150px);
  .left-card-box-select {
    height: 100%;
    padding: 10px;
    border: 1px solid #dddddd;
  }
}
</style>
